using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class NetUtils
{
		public static readonly Hashtable header = new Hashtable{
			{"Content-Type", "application/json"},
		};

		public static byte[] getPostData (object post)
		{
				if (post == null) {
						return null;
				}

				return SocketAdapter.Debug ? CommonUtils.jsonWrite (post) : CommonUtils.zipCompressValue (post);
		}

		public static T getReceiveValue<T> (byte[] receiveBytes, int pos)
		{
				if (pos < 0) {
						return default(T);
				}

				if (SocketAdapter.Debug) {
						if (typeof(T) == typeof(string)) {
								return (T)(object)Encoding.UTF8.GetString (receiveBytes, pos, receiveBytes.Length - pos);

						} else {
								return CommonUtils.jsonRead<T> (receiveBytes, pos, receiveBytes.Length - pos);
						}

				} else {
						return CommonUtils.zipDeCompressValue<T> (receiveBytes, pos, receiveBytes.Length - pos);
				}
		}

		public static CallBackDatas<int, byte[]> getReceiveCallBacks<T>(CallBackDatas<bool, T> callBackDatas)
		{
			return (pos, data)=>{
				if(pos < 0) {
					callBackDatas(false, default(T));
					
				} else {
					callBackDatas(true, getReceiveValue<T>(data, pos));
				}
			};
		}

		public static IEnumerator www<T> (string url, object post, CallBackDatas<WWW, T> callBacks, string dialogName)
		{
				return www (url, getPostData (post), callBacks, dialogName);
		}
	
		public static byte[] POST_DATA = new byte[]{0};
	
		public static IEnumerator www<T> (string url, byte[] postData, CallBackDatas<WWW, T> callBacks, string dialogName)
		{		
				if (postData == null) {
					postData = POST_DATA;
				}

				WWW www = new WWW (url, postData, header);
				MeDialog.showDialog (dialogName);
				T data = default(T);
				try {
						yield return www;
						if (www.error == null) {
								Dictionary<string, string> responseHeaders = www.responseHeaders;
								if (responseHeaders.ContainsKey ("SET-COOKIE")) {
										string cookie = www.responseHeaders ["SET-COOKIE"];
										if (cookie != null) {
												header.Remove ("COOKIE");
												header.Add ("COOKIE", cookie);
										}
								}
				
								if (SocketAdapter.Debug && typeof(T) == typeof(string)) {
										data = (T)(object)www.text;

								} else {
										data = getReceiveValue<T> (www.bytes, 0);
								}
						}
			
				} finally {
						MeDialog.closeDialog (dialogName);
						callBacks (www, data);
				}
		}

		public static void send (string url, object post, int callBackIndex)
		{
				SocketAdapter.Instance.send (Encoding.UTF8.GetBytes (url), getPostData (post), false, SocketAdapter.Debug, callBackIndex);
		}

		public static int TIME_OUT = 10000;

		public static void send<T> (string url, object post, CallBack timeoutCallBack, CallBackDatask<int, byte[], T> callBacksk, string dialogName)
		{
				//Debug.Log("NetUtilsSend:" + url + "=>" + dialogName);
				MeDialog.showDialog (dialogName);
				SocketAdapter.Instance.send (Encoding.UTF8.GetBytes (url), getPostData (post), TIME_OUT, () => {
						MeDialog.closeDialog (dialogName);
						if (timeoutCallBack != null) {
								timeoutCallBack ();

						}}, (pos, data) => {
						MeDialog.closeDialog (dialogName);
						if (callBacksk != null) {
								callBacksk (pos, data, getReceiveValue<T> (data, pos));
						}
				});
		}
	
		public static string RemoteDataPath;
		public static string PersistentDataPath = Application.persistentDataPath;
	
		public static IEnumerator wwwPersistent (string dataPath, CallBackData<WWW> callBack)
		{
				string pDataPath = PersistentDataPath + dataPath;
				FileInfo fileInfo = new FileInfo (pDataPath);
				bool persisted = fileInfo.Exists;
				pDataPath = fileInfo.Exists ? ("file://" + pDataPath) : (RemoteDataPath + dataPath);
				WWW www = new WWW (pDataPath);
				yield return www;
				if (www.error == null) {
						if (!persisted) {
								FileStream fileStream = fileInfo.Open(FileMode.CreateNew);
								try {
										byte[] bytes = www.bytes;
										fileStream.Write (bytes, 0, bytes.Length);
					
								} finally {
										fileStream.Close ();
								}
						}
			
						callBack (www);
			
				} else {
						//callBack (null);
				}
		}
}
